#include <stddef.h>
#include <windows.h>
#include <conio.h>

#ifndef _SYM_TUI_WIN_
#define _SYM_TUI_WIN_

inline bool moveCur(WORD x, WORD y){
	static COORD pos;
	pos.X=x, pos.Y=y;
	return SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
inline void putchar(WORD x, WORD y, char c, struct Console* cptr){
	if(x >= cptr->w || y >= cptr->h)
		return ;
	moveCur(x, y);
	putchar(c);
	moveCur(cptr->w-1, cptr->h-1);
}
inline void putcharWithoutChk(WORD x, WORD y, char c){
	moveCur(x, y);
	putchar(c);
}
inline void puts(WORD x, WORD y, WORD w, WORD h, const char* s, struct Console* cptr){
	static size_t i;
	if(x >= cptr->w || y >= cptr->h)
		return ;
	if(w==0)
		w = cptr->w-1-x;
	else
		w = minWORD(x+w, cptr->w-1)-x;
	if(h==0)
		h = cptr->h-1-y;
	else
		h = minWORD(y+h, cptr->h-1)-y;
	for(i=0; s[i] && i/w<h; ++i)
		putcharWithoutChk(x+(i%w), y+(i/w), s[i]);
	moveCur(cptr->w-1, cptr->h-1);
}
inline void getConsoleSize(WORD *columns, WORD *rows) {
	CONSOLE_SCREEN_BUFFER_INFO csbi;
	int ret;
	ret = GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
	if (ret) {
		*columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
		*rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
	} else {
		*columns = 80;  // Default fallback
		*rows = 25;     // Default fallback
	}
}
inline void clear(struct Console* cptr){
//	static WORD i, j;
//	for(i=0; i<cptr->w; ++i)
//		for(j=0; j<cptr->h; ++j)
//			putcharWithoutChk(i, j, ' ');
//	moveCur(0, 0);
	system("cls");
}
inline void resetTitle(const char* title){
	SetConsoleTitle(title);
}
inline void setUnicode(void){
	SetConsoleOutputCP(65001); 
}
inline void disableScl(void){
    HANDLE Hand;
    CONSOLE_SCREEN_BUFFER_INFO Info;
    Hand = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(Hand, &Info);
    SMALL_RECT rect = Info.srWindow;
    COORD size;
	size.X=rect.Right + 1;
	size.Y=rect.Bottom + 1;
    SetConsoleScreenBufferSize(Hand, size);
}
#endif
